home *** CD-ROM | disk | FTP | other *** search
- /* National Institute of Standards and Technology (NIST)
- /* National Computer System Laboratory (NCSL)
- /* Office Systems Engineering (OSE) Group
- /* ********************************************************************
- /* D I S C L A I M E R
- /* (March 8, 1989)
- /*
- /* There is no warranty for the NIST NCSL OSE SGML parser and/or the NIST
- /* NCSL OSE SGML parser validation suite. If the SGML parser and/or
- /* validation suite is modified by someone else and passed on, NIST wants
- /* the parser's recipients to know that what they have is not what NIST
- /* distributed, so that any problems introduced by others will not
- /* reflect on our reputation.
- /*
- /* Policies
- /*
- /* 1. Anyone may copy and distribute verbatim copies of the SGML source
- /* code as received in any medium.
- /*
- /* 2. Anyone may modify your copy or copies of SGML parser source code or
- /* any portion of it, and copy and distribute such modifications provided
- /* that all modifications are clearly associated with the entity that
- /* performs the modifications.
- /*
- /* NO WARRANTY
- /* ===========
- /*
- /* NIST PROVIDES ABSOLUTELY NO WARRANTY. THE SGML PARSER AND VALIDATION
- /* SUITE ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
- /* EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- /* THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
- /* WITH YOU. SHOULD THE SGML PARSER OR VALIDATION SUITE PROVE DEFECTIVE,
- /* YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
- /*
- /* IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL NIST BE LIABLE FOR
- /* DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
- /* INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
- /* INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
- /* BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
- /* FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
- /* NIST) THE PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
- /* SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
- */
-
- /************************************************************************/
- /* TITLE: SGML PARSER */
- /* SYSTEM: DTD PROCESSOR */
- /* SUBSYSTEM: */
- /* SOURCE FILE: PARSE1A.C */
- /* AUTHOR: Jim Heath */
- /* */
- /* DATE CREATED: */
- /* LAST MODIFIED: */
- /* */
- /* REVISIONS */
- /* WHEN WHO WHY */
- /************************************************************************/
- #include <stdio.h>
- #include <setjmp.h>
- #include <fcntl.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #define NAMELEN 8
- #include "../incs/dtd.h"
- #include "../incs/parse1a.h"
- /* ==================================================================== */
- #define CREATOPTS (O_CREAT|O_TRUNC|S_IWRITE|S_IREAD)
- /* ==================================================================== */
- SYMBREC symbol[MAXNODES];
- jmp_buf Xenv;
- TREENODE node[MAXNODES];
- int next, infile, outfile;
- /* ==================================================================== */
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int numtokens,firsttoken, root;
- char infname[128], outfname[128];
- DTDREC dtdrec;
- int i, j, k;
- TREENODE *nptr;
-
- strcpy(infname,"dtdfile1.sgm");
- strcpy(outfname,"dtdfile.sgm");
- if ((infile = open("dtdfile1.sgm", O_RDONLY)) == -1){
- printf("unable to open dtdfile1.sgm\n" );
- exit(1);
- }
- if ((outfile = creat("dtdfile.sgm", CREATOPTS)) == -1) {
- (void) close(infile);
- printf("unable to create dtdfile.sgm\n");
- exit(1);
- }
-
- if (read(infile, (char *) &numtokens, sizeof(numtokens)) != sizeof(numtokens))
- error("error in reading file");
- if (write(outfile, (char *) &numtokens, sizeof(numtokens)) != sizeof(numtokens))
- error("error in writing file");
- #ifdef JDEBUG
- printf("total tokens = %d\n", numtokens);
- #endif
- if (read(infile, &firsttoken, sizeof(firsttoken)) != sizeof(firsttoken))
- error("error in reading file");
- if (write(outfile, &firsttoken, sizeof(firsttoken)) != sizeof(firsttoken))
- error("error in writing file");
- bldsymbltbl(numtokens);
- if (setjmp(Xenv) != 0)
- goto DONE;
- for ( j = 0; j < numtokens; j++) {
- memset((char *) node, 0xFF, sizeof(node));
- next = 0;
- root = bldtree();
- #ifdef JDEBUG
- for (k = 0; k < next; k++)
- printnode(k);
- getchar();
- #endif
- traverse(root);
- for(i = k = 0; k < next; k++) {
- nptr = &node[i++];
- if (nptr->Tinfo == JUNK)
- continue;
- dtdrec.Dtoken = nptr->Tvalue;
- dtdrec.Doi = nptr->Toi;
- dtdrec.Dcontreq = nptr->Tcontext;
- if(write(outfile, &dtdrec, sizeof(dtdrec)) != sizeof(dtdrec))
- error("error in writing file");
- if (nptr->Tvalue == AND)
- if(write(outfile, &nptr->Tandcount, sizeof(nptr->Tandcount)) != sizeof(nptr->Tandcount))
- error("error in writing file");
- }
- }
- DONE:
- (void) close(infile);
- (void) close(outfile);
- (void) unlink(infname);
- }
- /* ==================================================================== */
- void bldsymbltbl(numtokens)
- int numtokens;
- {
- int j;
- char tempname[128];
- for (j = 0; j < numtokens; j++){
- if (j >= (MAXNODES - 1))
- error("overflow while building symbol table");
- if (read(infile, &symbol[j], sizeof(symbol[j])) != sizeof(symbol[j]))
- error("error in reading file");
- if (write(outfile, &symbol[j], sizeof(symbol[j])) != sizeof(symbol[j]))
- error("error in reading file");
- memset(tempname, '\0', sizeof(tempname));
- strncpy(tempname, symbol[j].Sname, 8);
- tempname[8] = '\0';
- #ifdef JDEBUG
- if (symbol[j].Smin == 0)
- printf("- - ");
- else if (symbol[j].Smin == 1)
- printf("O - ");
- else if (symbol[j].Smin == 2)
- printf("- O ");
- else if (symbol[j].Smin == 3)
- printf("O O ");
- symbol[j].Sname[NAMELEN - 1] = '\0';
- printf("NAME = %s; tokennbr = %03d\n", tempname, symbol[j].Sid);
- #endif
- }
- }
- /* ==================================================================== */
- int bldtree()
- {
- DTDREC dtdrec;
- int index, andcount;
- TREENODE *nptr;
-
- if (read(infile, &dtdrec, sizeof(dtdrec)) <= 0)
- longjmp(Xenv, 1);
- else {
- if (next >= (MAXNODES - 1) )
- error("max nodes has been exceeded");
- nptr = &node[index = next++];
- switch(dtdrec.Dtoken) {
- case COMMA:
- case OR:
- nptr->Tvalue = dtdrec.Dtoken;
- nptr->Toi = dtdrec.Doi;
- nptr->Tcontext = dtdrec.Dcontreq;
- nptr->Tleft = bldtree();
- nptr->Tright = bldtree();
- return(index);
- case AND:
- nptr->Tvalue = dtdrec.Dtoken;
- nptr->Toi = dtdrec.Doi;
- nptr->Tcontext = dtdrec.Dcontreq;
- if (read(infile, &nptr->Tandcount, sizeof(nptr->Tandcount)) != sizeof(nptr->Tandcount))
- error("error in file read");
- #ifdef OLD
- for (temp = next - 1, j = 0; j < nptr->Tandcount; j++)
- node[temp++].Tleft = bldtree();
- return(index);
- #endif
- andcount = nptr->Tandcount;
- while(1) {
- nptr->Tleft = bldtree();
- if(--andcount == 1){
- nptr->Tright = bldtree();
- return(index);
- }
- nptr->Tright = next;
- if (next >= (MAXNODES - 1) )
- error("max nodes has been exceeded");
- nptr = &node[next++];
- nptr->Tvalue = AND;
- nptr->Toi = '1';
- nptr->Tinfo = JUNK;
- }
- case -1: /* PCDATA */
- case -3: /* RCDATA */
- case -4: /* CDATA */
- case -5: /* EMPTY */
- case -6: /* ANY */
- nptr->Tvalue = dtdrec.Dtoken;
- nptr->Toi = dtdrec.Doi;
- nptr->Tcontext = dtdrec.Dcontreq;
- nptr->Tleft = nptr->Tright = -1;
- return(index);
- default:
- nptr->Tvalue = dtdrec.Dtoken;
- nptr->Toi = dtdrec.Doi;
- nptr->Tcontext = dtdrec.Dcontreq;
- nptr->Tleft = nptr->Tright = -1;
- return(index);
- }
- }
- }
- /* ==================================================================== */
- void traverse(index)
- int index;
- {
- TREENODE *nptr = &node[index];
- int retval;
-
- if (ISTERMINAL(nptr->Tvalue)) {
- if (ISOPTIONAL(nptr->Toi))
- nptr->Tcontext = C_NEVERO;
- else if (nptr->Toi == '+')
- nptr->Tcontext = C_FTO;
- else
- nptr->Tcontext = C_ALWAYSO;
- #ifdef JDEBUG
- printf("traversing on NODE[%d], %s\n",index, getmsg(nptr->Tcontext));
- #endif
- }
- else {
- retval = traverseleft(nptr->Tleft, nptr->Tvalue, nptr->Toi);
- #ifdef JDEBUG
- printf("traversing on NODE[%d]\n",index);
- #endif
- (void) traverseright(nptr->Tright, nptr->Tvalue, nptr->Toi, retval);
- }
- }
- /* ==================================================================== */
- int traverseleft(index, lastconnector, groupoi)
- int index, lastconnector, groupoi;
- {
- TREENODE *nptr = &node[index];
- int tempoi, retvalleft, retvalright;
- enum CONTEXT savecontext;
-
- savecontext = nptr->Tcontext;
-
- if (ISTERMINAL(nptr->Tvalue)) {
- if (ISOPTIONAL(nptr->Toi))
- nptr->Tcontext = C_NEVERO;
- else if (lastconnector == AND)
- nptr->Tcontext = C_NEVERO;
- else if (lastconnector == OR)
- nptr->Tcontext = C_NEVERO;
- else if (ISOPTIONAL(groupoi))
- nptr->Tcontext = C_NEVERO;
- else if (groupoi == '+')
- nptr->Tcontext = C_FTO;
- else if (nptr->Toi == '+')
- nptr->Tcontext = C_FTO;
- else
- nptr->Tcontext = C_ALWAYSO;
- #ifdef JDEBUG
- printf("traversing on NODE[%d], %s\n",index, getmsg(nptr->Tcontext));
- #endif
- /* nptr->Tcontext = savecontext;*/
- return(nptr->Toi);
- }
-
- tempoi = oifnc(nptr->Toi, nptr->Tvalue, lastconnector, groupoi);
- retvalleft = traverseleft(nptr->Tleft, nptr->Tvalue, tempoi);
- #ifdef JDEBUG
- printf("traversing on NODE[%d]\n",index);
- #endif
- retvalright = traverseright(nptr->Tright, nptr->Tvalue, tempoi, retvalleft);
- return(reqmntfnc(nptr->Tvalue, nptr->Toi, retvalleft, retvalright));
- }
- /* ==================================================================== */
- int traverseright(index, lastconnector, groupoi, leftoi)
- int index, lastconnector, groupoi, leftoi;
- {
- TREENODE *nptr = &node[index];
- int retvalleft, retvalright;
- enum CONTEXT savecontext;
-
- savecontext = nptr->Tcontext;
- if (ISTERMINAL(nptr->Tvalue)) {
- if ((lastconnector == OR) || (lastconnector == AND))
- nptr->Tcontext = C_NEVERO;
- else if (ISOPTIONAL(nptr->Toi))
- nptr->Tcontext = C_NEVERO;
- else if (ISOPTIONAL(leftoi)) {
- if (ISOPTIONAL(groupoi))
- nptr->Tcontext = C_SOMETIMESO;
- else if (groupoi == '+')
- nptr->Tcontext = C_FTOTSO;
- else if (groupoi == '1')
- nptr->Tcontext = C_ALWAYSO;
- }
- /* leftoi is not optional */
- else if ((groupoi == '+') && (nptr->Toi == '+'))
- nptr->Tcontext = C_FTOWR;
- else if (nptr->Toi == '+')
- nptr->Tcontext = C_FTO;
- else
- nptr->Tcontext = C_ALWAYSO;
-
- #ifdef JDEBUG
- printf("traversing on NODE[%d], %s\n",index, getmsg(nptr->Tcontext));
- #endif
- /* nptr->Tcontext = savecontext;*/
- return(nptr->Toi);
- }
- retvalleft = traverseleft(nptr->Tleft, nptr->Tvalue, nptr->Toi);
- #ifdef JDEBUG
- printf("traversing on NODE[%d]\n",index);
- #endif
- retvalright = traverseright(nptr->Tright, nptr->Tvalue, nptr->Toi, retvalleft);
- return(reqmntfnc(nptr->Tvalue, nptr->Toi, retvalleft, retvalright));
- }
- /* ==================================================================== */
- int oifnc(curroi, currval, lastconnector, prevoi)
- int curroi, currval, lastconnector, prevoi;
- {
- if ((lastconnector == AND) || (lastconnector == OR))
- return('?');
- if (ISOPTIONAL(prevoi) && (currval == COMMA))
- return(prevoi);
- if ((currval == AND) || (currval == OR))
- return('?');
- return(curroi);
- }
- /* ==================================================================== */
- void printnode(k)
- int k;
- {
- TREENODE *nptr = &node[k];
- char tvalue[16];
- switch (nptr->Tvalue) {
- case COMMA:
- strcpy(tvalue, "COMMA");
- break;
- case OR:
- strcpy(tvalue, "OR");
- break;
- case AND:
- strcpy(tvalue, "AND");
- break;
- default:
- printf("NODE[%d] left = %d, right = %d, value = %s, oi = %c\n",
- k, nptr->Tleft, nptr->Tright, symbol[nptr->Tvalue].Sname, nptr->Toi);
- return;
- }
- printf("NODE[%d] left = %d, right = %d, value = %s, oi = %c\n",
- k, nptr->Tleft, nptr->Tright, tvalue, nptr->Toi);
- }
- /* ==================================================================== */
-
- /*----------------------------------------------*/
- /* HEADING */
- /* Simply prints a informatory heading */
- /* when the document parser is invoked */
- /* describing the document name to be */
- /* parsed. */
- /*----------------------------------------------*/
-
- void heading()
- {
- printf("\n DTDFILE Decoder\n");
- printf(" Decodes DTDFILES built by PARSE2\n");
- printf(" --------------------------------------------------\n");
- printf(" 03Nov86 Version 1.01\n");
- printf(" --------------------------------------------------\n\n");
- return;
- }
- /* ==================================================================== */
- void error(msg)
- char *msg;
- {
- (void) close(infile);
- (void) close(outfile);
- printf(msg);
- exit(1);
- }
- /* ==================================================================== */
- void doopts(argc, argv, infname, outfname)
- int argc;
- char *argv[];
- char *infname, *outfname;
- {
- }
- /* ==================================================================== */
- char *getmsg(x)
- enum CONTEXT x;
- {
- switch (x) {
- case C_NEVERO:
- return("<start tag is never omissable>");
- case C_ALWAYSO:
- return("<start tag is always omissable>");
- case C_SOMETIMESO:
- return("<start tag is sometimes omissable>");
- case C_FTO:
- return("<start tag is omissable first time only>");
- case C_FTOWR:
- return("<start tag is omissable FTO with reset>");
- case C_FTOTSO:
- return("<start tag is omissable FTO then sometimes>");
- default:
- return("UNKNOWN ARGUMENT TO GETMSG()");
- }
- }
- /* ==================================================================== */
- int reqmntfnc(connector, oi, oileft, oiright)
- int connector, oileft, oiright;
- {
- if(ISOPTIONAL(oi))
- return(oi);
- switch (connector) {
- case COMMA:
- case AND:
- if(ISOPTIONAL(oileft) && ISOPTIONAL(oiright))
- return'?';
- return(oi);
- case OR:
- if(ISOPTIONAL(oileft) || ISOPTIONAL(oiright))
- return'?';
- return(oi);
- default:
- printf("illegal value to reqmntfnc()\n");
- exit(1);
- }
- }
-
-